Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[canvas] Create Expression Factories; remove legacy search service #107353

Closed

Conversation

clintandrewhall
Copy link
Contributor

@clintandrewhall clintandrewhall commented Aug 2, 2021

Reviewable portion of #103202

Summary

This PR creates a new Expressions Function Definition Factory, so plugin lifecycle dependencies can be provided to the function definitions when they are added to the Expressions plugin, rather than accessing a module-level singleton.

Since the only dependencies on the legacy search service were these functions, I've also deleted the legacy service.

This also reconfigures our i18n to co-locate the strings, introduces a new Factory type (that might be interest to @elastic/kibana-app-services and @ppisljar), and alters the Canvas Plugin API to include a setter.

What is this?

In #88112 the Presentation Team created a Service Abstraction API which allows any of our solutions to uniformly (and safely) create abstractions between external services and the means by which we use them. It also provides a standard method for "swapping" service implementations at "start" time, (e.g. Kibana setup/start, or Storybook start, or Jest setup, etc). That means, for example, Storybook Controls can give arguments to the services to adjust mocks on-the-fly from the Storybook application.

For more information, check out the docs.

Canvas already had a rough service abstraction layer that was a bit rigid, but was also unsafe: the singleton providing services was defined as a module-level constant. This means it exists and can be accessed outside the setup/start lifecycle of a Kibana plugin. 😞

This forthcoming collection of PRs moves each individual service abstraction to our "official" API and removes the legacy service. This makes it easier to review and test each service.

@clintandrewhall clintandrewhall added review Team:Presentation Presentation Team for Dashboard, Input Controls, and Canvas loe:small Small Level of Effort v8.0.0 release_note:skip Skip the PR/issue when compiling release notes impact:medium Addressing this issue will have a medium level of impact on the quality/strength of our product. Feature:Canvas v7.15.0 labels Aug 2, 2021
@clintandrewhall clintandrewhall requested a review from a team as a code owner August 2, 2021 02:12
@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-presentation (Team:Presentation)

@clintandrewhall clintandrewhall changed the title [canvas] Create Search Service; remove legacy service [canvas] Create Expression Factories; remove legacy search service Aug 2, 2021
@clintandrewhall clintandrewhall force-pushed the canvas/search-service branch 3 times, most recently from 9dc2025 to c59683a Compare August 2, 2021 18:59
@clintandrewhall clintandrewhall added the auto-backport Deprecated - use backport:version if exact versions are needed label Aug 2, 2021
Copy link
Contributor

@poffdeluxe poffdeluxe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This pattern looks good! Should be easy to pick it up and move it whenever it's time to move these functions elsewhere.

@clintandrewhall clintandrewhall force-pushed the canvas/search-service branch 2 times, most recently from 1908cf9 to 807604b Compare August 3, 2021 04:50
@@ -37,9 +40,10 @@ export class CanvasSrcPlugin implements Plugin<void, void, SetupDeps, StartDeps>

plugins.canvas.addRenderers(renderFunctions);

core.getStartServices().then(([coreStart, depsStart]) => {
core.getStartServices().then(([coreStart, startPlugins]) => {
Copy link
Member

@ppisljar ppisljar Aug 3, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this doesn't look right. you await core.getStartServices() here which will only resolve once the start lifectcle completes. this means that your setup lifecycle actually completes after start.

what you should rather do is pass core.getStartServices method to your factory and await on it inside your function body. this way the setup lifecycle will be done in time as we'll only await on start services when running the function (which can only happen after start lifecycle)

also its not clear to me if this functions are reistered on both client and server (they should be)

take a look at how data plugin does it for example:
here we are registering a function and passing core.getStartServices to the factory
here and here you can see how we wrap core services so we can pass a common thing to the function on client and server. note that this is still just async function being passed to actual kibana_context factory (so nothing executed/awaited for at setup time)
here you can see that how we await on core.getStartServices inside function body of kibana_context

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I've been looking this over, and this feedback is entirely valid and really important, but unfortunately I don't think it can be addressed in this PR. We will most certainly address it in #105675.

@ppisljar My choices are to commit as-is, or fix this one case the correct way and leave the others. How do you feel about me committing this to match the current (admittedly incorrect) pattern and fix all of this in #105675? Otherwise this legacy service is going to have to stick around until we address #105675.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am fine leaving this as it is in this PR, we are not changing it for worse and if you think you are gonna reach the end goal easier in steps that is completely ok with me.

@clintandrewhall clintandrewhall enabled auto-merge (squash) August 13, 2021 22:32
@kibanamachine
Copy link
Contributor

💚 Build Succeeded

Metrics [docs]

Module Count

Fewer modules leads to a faster build time

id before after diff
canvas 1044 1039 -5

Async chunks

Total size of all lazy-loaded chunks that will be downloaded as the user navigates the app

id before after diff
canvas 1.6MB 1.6MB -1.4KB

Page load bundle

Size of the bundles that are downloaded on every page load. Target size is below 100kb

id before after diff
canvas 28.2KB 28.4KB +130.0B
Unknown metric groups

API count

id before after diff
canvas 6 4 -2

API count missing comments

id before after diff
canvas 5 3 -2

Non-exported public API item count

id before after diff
canvas 3 1 -2

History

  • 💚 Build #145059 succeeded 5a7cc367dfde43ca6d9e0625da14fe19b0f30005
  • 💚 Build #142543 succeeded 807604bd0e323e13deeb8f2f1beaa52f23fe7dc1
  • 💔 Build #142518 failed 1908cf9fcd764a4580c840104f9668a597d42b14
  • 💚 Build #142447 succeeded c59683a4d64e17cc16442e4a163d51fb3598ba83
  • 💚 Build #142422 succeeded 9dc2025bafef4c4ff329d0137e03c86be00d87c6

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

@@ -37,9 +40,10 @@ export class CanvasSrcPlugin implements Plugin<void, void, SetupDeps, StartDeps>

plugins.canvas.addRenderers(renderFunctions);

core.getStartServices().then(([coreStart, depsStart]) => {
core.getStartServices().then(([coreStart, startPlugins]) => {
plugins.canvas.addFunctionFactories(factories, { coreStart, startPlugins });
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This abstraction feels to general to me and not general enough on the other hand.

We are giving whole coreStart and all plugins start contracts to each factory. Most factories need a single thing. And possibly it could be something that is not provided on any start contract (but something internal to the plugin providing the function). When you will try to use this code on the server you will have a lot of problems as server and client side start contracts don't look the same.

I think we should rather call each factory here and provide it just what it needs.

  plugins.canvas.registerFunction(esdocsFactory({ search: startPlugins.data.search) });

this will make it clearer what the dependencies are, it will make it easier to make code available on the server (you will only need to abstract search behind a common server/client interface) and it gives flexibility for whatever random thing you need to provide to some other functions in the future.

@mistic mistic added v7.16.0 and removed v7.15.0 labels Aug 18, 2021
@spalger spalger added v7.17.0 and removed v7.16.0 labels Dec 7, 2021
auto-merge was automatically disabled December 29, 2021 17:49

Pull request was closed

@clintandrewhall clintandrewhall deleted the canvas/search-service branch December 29, 2021 17:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
auto-backport Deprecated - use backport:version if exact versions are needed Feature:Canvas impact:medium Addressing this issue will have a medium level of impact on the quality/strength of our product. loe:small Small Level of Effort release_note:skip Skip the PR/issue when compiling release notes review Team:Presentation Presentation Team for Dashboard, Input Controls, and Canvas v7.17.0 v8.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants